'''
Created on 19/08/2012

@author: Nrai
'''

from src.ex import paletteexceptions
import array

class Palette(object):
    
    '''
    Class for working with palette files
    Accepts: 
            Palette files (ex: palette.act)
            
            A nested list for each color
            each color is a list of n elements where
            n is the amount of channels, ex: RGB is [R,G,B]
            
            A unicode string of channels of length depending
            on the palette file (ex: .act files are 768 channels
            long)
    '''
        
    def __init__(self, palette):
        
        self.palette_handler(palette)
    
    def encode(self, option):
        pass
    
    def decode (self):
        pass
    
    def palette_handler(self, palette):
        
        palette_type = type(palette)
        if palette_type is file:
            pass
        if palette_type is list:
            pass
        if palette_type is str:
            pass
    
    def _palette_dispatcher(self):
        pass
    
    
class PaletteDispatcher(object):
    
    def __init__(self):
        pass
    
    def file_to_clist(self):
        pass
    
    def file_to_ustring(self):
        pass
    
    def clist_to_file(self, clist, file_ext):
        
        pass
    
    def ustring_to_file(self):
        pass
    
    def validate_file(self, pfile, ext="act", length=768):
        
        '''
        Validate that the palette object is of type file
        Validates the extension of the file.
        Validates the length of the file.
        '''
        try:
            ftype = type(pfile)
            assert ftype is type
        except AssertionError:
            raise paletteexceptions.PaletteFileError(
                                                     "%s must be a file object" 
                                                     % pfile.name
                                                     )
        try:
            pfile_ext = pfile.name.split(".")[1]
            assert pfile_ext is ext
        except AssertionError:
            raise paletteexceptions.PaletteFileError(pfile.name)
        try:
            sof, eof = 0, 2
            pfile.seek(sof, eof)
            plength = pfile.tell()
            assert plength.tell() is length
        except AssertionError:
            pfile.close()
            raise paletteexceptions.PaletteLengthError(length, plength)
        pfile.seek(sof)
        return True
        
    
    
    def validate_ustring(self, ustring, length=768):
        
        ''' 
            Validates the length of the string,
            That every character is decoded as an int,
            That every int ranges from 0 to 255
            
            Length can be specified for particular file type
            default is 768 for .act files
        '''
        
        try:
            "Asserts the length of the string"
            plength = len(ustring)
            assert plength is length
        except AssertionError:
            raise paletteexceptions.PaletteLengthError(length, plength)
        for char in ustring:
            try:
                "Tries to convert the char to it's int unicode"
                char = ord(char)
                try:
                    "Asserts that the result was an int"
                    assert type(char) is int
                except AssertionError:
                    raise paletteexceptions.PaletteValueError(char)
                try:
                    "Asserts that the int is in range 0-255"
                    assert char >=0 and char <= 255
                except AssertionError:
                    raise paletteexceptions.PaletteRangeError(char)
            except TypeError:
                raise paletteexceptions.PaletteFormatError(char)
        return True
      
                
    def validate_clist(self, clist, length=256, channels=3):
        
        '''
            Receives a nested list with colors.
            Validates the length of the list
            Validates the length of each color(channels)
            Validates that each channel is an int
            Validates that each channel ranges from 0 to 255.
        '''
        
        try:
            assert type(clist) is list
        except AssertionError:
            raise paletteexceptions.PaletteError("Palette must be a list")
        try:
            clength = len(clist)
            assert clength is length
        except AssertionError:
            raise paletteexceptions.PaletteLengthError(length, clength)
            
        for color in clist:
            try:
                assert type(color) is list
            except AssertionError:
                raise paletteexceptions.PaletteError("Color must be a list")
            try:
                cchannels = len(color)
                assert cchannels is channels
            except AssertionError:
                raise paletteexceptions.PaletteLengthError(channels, cchannels)
            for channel in color:
                try:
                    assert type(channel) is int
                except AssertionError:
                    raise paletteexceptions.PaletteValueError(channel)
                try:
                    assert channel >= 0 and channel <= 255
                except AssertionError:
                    raise paletteexceptions.PaletteRangeError(channel)
        return True

def act_palette_decoder():
    pass